#!/usr/bin/perl
#
# Find the oldest people in the DB and try to freeze them, if appropriate
# - or update their logintime, if that's appropriate
#

use Counter;
use Getopt::Long;
use POSIX qw(O_RDWR strftime);
use NoteHandler;

$count = 20;
$age = 730;

GetOptions("test" => \$test,
	"count=i" => \$count);

Counter::open(O_RDWR);

$users = Counter::openfile("users");

@oldfolks = $users->select("state <> 'frozen' and state <> 'blocked'"
			   . " order by logintime limit $count");
$n = new NoteHandler;

$old = strftime "%Y-%m-%d %H:%M:%S", gmtime(time()-($age*3600*24));
# Don't freeze entries where person has been touched in 2 weeks
$quiettime = strftime "%Y-%m-%d %H:%M:%S", gmtime(time()-(14*3600*24));


for $user (@oldfolks) {
    my $logintimechanged;
    my $oldlogintime = $$user{logintime};
    $n->start($user->key());
    if ($user->{state} eq "frozen") {
	if ($user->guesslogintime()) {
	    $user->store();
	    $n->done("Already frozen - new logintime");
	} else {
	    $n->done("Already frozen");
	}
    } else {
	if ($user->guesslogintime()) {
	    $logintimechanged = 1;
	}
	# Bughunting...
	if (!$user->{logintime}) {
	    $n->note("Logintime still missing after guess");
	    #die("Please fix error\n");
	    $n->done("Logintime unguessable");
	    next;
	}
	if ($user->{logintime} lt $old) {
	    $person = $user->person();
	    if ($person && $person->{f_mtime} gt $quiettime) {
		$n->note("Not freezing - person mtime $$person{f_mtime}");
		$n->done("Not freezing - logintime old, but person touched");
	    } elsif ($logintimechanged) {
		$n->note("Freezing - logintime from '$oldlogintime' to  $$user{logintime}");
		$user->freeze() if !$test;
		$n->done("Frozen - new logintime");
	    } else {
		$n->note("Freezing - old: logintime $$user{logintime}");
		$user->freeze() if !$test;
		$n->done("Frozen - old logintime");
	    }
	} elsif ($logintimechanged) {
	    $user->store() if !$test;
	    $n->done("Not old - new logintime");
	} else {
	    $n->done("Not old - same logintime");
	}
    }
}
$n->report();


# This method to be transferred into Counter::User module

package Counter::User;

use HTTP::Date;

sub guesslogintime {
    my $self = shift;
    my $guess;

    $guess = $$self{logintime};
    # reformat some entries that had a compact version of date
    if ($guess =~ /^(\d{4})(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)$/) {
	$guess = "$1-$2-$3 $4:$5:$6";
    }
    # Look for activity done by this user after guesstime.
    # Check: Created after logintime?
    if ($$self{f_ctime} gt $guess) {
	$guess = $$self{f_ctime};
    }
    # Check: Person created after logintime?
    $pers = $self->person();
    if ($$pers{f_ctime} gt $guess) {
	$guess = $$pers{f_ctime};
    }
    # Check: A machine created after logintime?
    @mach = $self->machines();
    for $mach (@mach) {
	if ($mach->{f_ctime} gt $guess) {
	    $guess = $mach->{f_ctime};
	}
    }
    # If activity detected after logintime, update
    if ($guess ne $$self{logintime}) {
	# Convert both logintime and guess to timestamps
	my $tself = HTTP::Date::str2time($$self{logintime});
	my $tguess = HTTP::Date::str2time($guess);
	# Update only if guess is 1 hour or more after logintime
	if ($tself + 3600 < $tguess) {
	    $$self{logintime} = $guess;
	    return 1;
	} else {
	    # Debug
	    #warn "Ignoring change of ", $tguess - $tself, " seconds from ",
	    #$$self{logintime}, " to ", $guess, "\n";
	    return 0;
	}
    } else {
	return 0;
    }
}
